using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Rilisoft.MiniJson;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace BCW.Friends
{
	public class FriendsController : MonoBehaviour
	{
		public static FriendsController instance;

		public bool showLogs;

		public Dictionary<string, Conversation> chat = new Dictionary<string, Conversation>();

		private Dictionary<string, List<Message>> newMessages = new Dictionary<string, List<Message>>();

		private Dictionary<long, Message> messagesToSend = new Dictionary<long, Message>();

		private List<string> _friendsIds = new List<string>();

		private List<string> _invitesIds = new List<string>();

		private List<string> _newFriendsIds = new List<string>();

		private List<string> _lastFriendsIds = new List<string>();

		private List<string> _lastInviteIds = new List<string>();

		public Dictionary<string, long> timeStamps = new Dictionary<string, long>();

		public List<string> friendsFakeIds = new List<string>();

		public Dictionary<string, PlayerInfo> playerFakeDB = new Dictionary<string, PlayerInfo>();

		private List<string> _idsFrinedsInviteToBattle = new List<string>();

		private uint _countNewMessages1;

		private uint _countNewFriends;

		private float _friendsRequestTime = 20f;

		private float _friendsRequestTimeInChat = 15f;

		private float _updatePlayerDBTime = 25f;

		private string keyCountUnreadMessages = "BCWfriendsUnreadMessagesCount";

		private bool unreadMessagesLoaded;

		private bool canRequestInfo = true;

		private string keyTimestamps = "FriendKeyTimestamps";

		private string keyArrays = "FriendAndInvitesIdsArrayKeys";

		private string _chatHistoryPrefix = "ChatHistory_";

		public ReadOnlyCollection<string> FriendsIds
		{
			get
			{
				return _friendsIds.AsReadOnly();
			}
		}

		public ReadOnlyCollection<string> InvitesIds
		{
			get
			{
				return _invitesIds.AsReadOnly();
			}
		}

		public Dictionary<string, PlayerInfo> playerDB
		{
			get
			{
				return FriendsPlayerStorage.GetInstance().PlayerDB;
			}
		}

		public List<string> IdsFrinedsInviteToBattle
		{
			get
			{
				return _idsFrinedsInviteToBattle;
			}
		}

		public uint CountNewMessages
		{
			get
			{
				uint num = 0u;
				foreach (KeyValuePair<string, Conversation> item in chat)
				{
					num += item.Value.unreadMessages;
				}
				return num;
			}
		}

		public uint CountNewFriends
		{
			get
			{
				return _countNewFriends;
			}
			set
			{
				_countNewFriends = 0u;
			}
		}

		public static event Action OnIdsListsUpdated;

		public static event Action<Dictionary<string, uint>> OnReciveNewMessages;

		public static event Action OnReciveNewFriends;

		public static event Action OnReciveNewInvites;

		public static event Action OnUpdateMessageCount;

		public static event Action OnUpdatePlayerDB;

		public static event Action<string> OnNewBattleInvite;

		public static event Action OnUpdateTimestamps;

		public Dictionary<string, PlayerInfo> getPlayerDBWithFake()
		{
			Dictionary<string, PlayerInfo> dictionary = new Dictionary<string, PlayerInfo>();
			foreach (string key in playerDB.Keys)
			{
				dictionary[key] = playerDB[key];
			}
			foreach (string key2 in playerFakeDB.Keys)
			{
				dictionary[key2] = playerFakeDB[key2];
			}
			return dictionary;
		}

		public ReadOnlyCollection<string> FriendsIdsWithFake()
		{
			List<string> list = new List<string>();
			list.AddRange(_friendsIds);
			list.AddRange(friendsFakeIds);
			return list.AsReadOnly();
		}

		public void RequestPlayerInfo(List<string> idPlayers, Action OnComplete, bool force = false)
		{
			StartCoroutine(RequestsPlayerInfoCoroutine(idPlayers, OnComplete, force, false));
		}

		public void UpdatePlayersDB(Action OnComplete)
		{
			List<string> list = new List<string>(_friendsIds.ToArray());
			list.AddRange(_invitesIds.ToArray());
			if (list.Count > 0)
			{
				StartCoroutine(RequestsPlayerInfoCoroutine(list, OnComplete));
				return;
			}
			if (OnComplete != null)
			{
				OnComplete();
			}
			FriendsPlayerStorage.GetInstance().Save();
		}

		public List<PlayerInfo> GetFiendsList()
		{
			List<PlayerInfo> list = new List<PlayerInfo>();
			List<string> list2 = new List<string>();
			Dictionary<string, PlayerInfo> playerDBWithFake = instance.getPlayerDBWithFake();
			foreach (string item in instance.FriendsIdsWithFake())
			{
				if (playerDBWithFake.ContainsKey(item))
				{
					list.Add(playerDBWithFake[item]);
				}
			}
			list.Sort(delegate(PlayerInfo x, PlayerInfo y)
			{
				if (!timeStamps.ContainsKey(x.playerId) || timeStamps[x.playerId] == 0L)
				{
					return 1;
				}
				return (!timeStamps.ContainsKey(y.playerId) || timeStamps[y.playerId] == 0L) ? (-1) : (timeStamps[x.playerId].CompareTo(timeStamps[y.playerId]) * -1);
			});
			if (list2.Count > 0)
			{
				instance.RequestPlayerInfo(list2, null);
			}
			return list;
		}

		public void RemoveNewStatus(string id)
		{
			if (FriendsController.OnReciveNewFriends != null)
			{
				FriendsController.OnReciveNewFriends();
			}
		}

		public void RemoveNewStatus()
		{
			foreach (string newFriendsId in _newFriendsIds)
			{
				if (playerDB.ContainsKey(newFriendsId))
				{
					PlayerInfo value = playerDB[newFriendsId];
					value.isNew = false;
					playerDB[newFriendsId] = value;
				}
			}
			_newFriendsIds.Clear();
		}

		public void FindPlayer(string request, Action<List<PlayerInfo>> OnComplete)
		{
			StartCoroutine(FindPlayerIEnumerator(request, OnComplete));
		}

		public void InviteFriend(string idPlayer, Action<ServerResponse> OnComplete)
		{
			StartCoroutine(FriendManagementTemplate(idPlayer, "request_friend", OnComplete));
		}

		public void AcceptInvite(string idPlayer, Action<ServerResponse> OnComplete)
		{
			StartCoroutine(FriendManagementTemplate(idPlayer, "accept_friendship_invite", OnComplete));
		}

		public void RejectInvite(string idPlayer, Action<ServerResponse> OnComplete)
		{
			StartCoroutine(FriendManagementTemplate(idPlayer, "reject_friendship_invite", OnComplete));
		}

		public void RemoveFriend(string idPlayer, Action<ServerResponse> OnComplete)
		{
			StartCoroutine(FriendManagementTemplate(idPlayer, "reject_friend", OnComplete));
		}

		public void InviteFriendToBattle(List<string> idPlayers, Action<ServerResponse> OnComplete)
		{
			StartCoroutine(InviteFriendToBattleIENumerator(idPlayers, OnComplete));
		}

		public bool IsFriend(string playerId)
		{
			return FriendsIds.Contains(playerId);
		}

		public void ClearBattleInvites()
		{
			foreach (string friendsId in FriendsIds)
			{
				if (playerDB.ContainsKey(friendsId))
				{
					PlayerInfo value = playerDB[friendsId];
					value.inviteToBattle = false;
					playerDB[friendsId] = value;
				}
			}
		}

		public bool AddMessage(string idPlayer, string text, long messageId)
		{
			if (!messagesToSend.ContainsKey(messageId))
			{
				Message message = new Message();
				message.playerId = idPlayer;
				message.text = text;
				message.isMine = true;
				message.messageId = messageId;
				messagesToSend.Add(messageId, message);
				StartCoroutine(RequestFriendAndInviteLists());
				return true;
			}
			return false;
		}

		public List<Message> GetMessages(string idPlayer)
		{
			List<Message> list = new List<Message>();
			if (!chat.ContainsKey(idPlayer))
			{
				chat.Add(idPlayer, new Conversation());
			}
			if (!chat[idPlayer].historyLoaded)
			{
				LoadChatHistory(idPlayer);
				chat[idPlayer].Sort();
				chat[idPlayer].historyLoaded = true;
			}
			chat[idPlayer].unreadMessages = 0u;
			list.AddRange(chat[idPlayer].messages.ToArray());
			foreach (KeyValuePair<long, Message> item in messagesToSend)
			{
				if (item.Value.playerId.Equals(idPlayer))
				{
					list.Add(item.Value);
				}
			}
			if (newMessages.ContainsKey(idPlayer))
			{
				newMessages.Remove(idPlayer);
			}
			if (FriendsController.OnUpdateMessageCount != null)
			{
				FriendsController.OnUpdateMessageCount();
			}
			return list;
		}

		public List<Message> GetNewMessages(string idPlayer)
		{
			List<Message> list = new List<Message>();
			if (newMessages.ContainsKey(idPlayer))
			{
				chat[idPlayer].unreadMessages = 0u;
				list.AddRange(newMessages[idPlayer].ToArray());
				newMessages.Remove(idPlayer);
			}
			if (FriendsController.OnUpdateMessageCount != null)
			{
				FriendsController.OnUpdateMessageCount();
			}
			return list;
		}

		public Dictionary<string, uint> GetCountNewMessages()
		{
			Dictionary<string, uint> dictionary = new Dictionary<string, uint>();
			foreach (KeyValuePair<string, Conversation> item in chat)
			{
				if (!dictionary.ContainsKey(item.Key))
				{
					dictionary.Add(item.Key, item.Value.unreadMessages);
				}
			}
			return dictionary;
		}

		private void Awake()
		{
			UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
			instance = this;
			ParseSettingsJson(JSONManager.Instance.GetJSON(URLs.FriendsSettings));
			LoadFriendsAndInvites();
			LoadTimestamps();
			StartCoroutine(UpdateFriends());
		}

		private void OnDestroy()
		{
			instance = null;
		}

		private void OnApplicationPause(bool isPause)
		{
			if (isPause)
			{
				SaveChatHistory();
				SaveFriendsAndInvites();
				SaveUnreadMessages();
				SaveTimestamps();
			}
		}

		public void SaveUnreadMessages()
		{
			foreach (KeyValuePair<string, Conversation> item in chat)
			{
				Save.SaveInt(keyCountUnreadMessages + "_" + item.Key, (int)item.Value.unreadMessages);
			}
		}

		public void LoadUnreadMessages()
		{
			if (_friendsIds.Count <= 0 || unreadMessagesLoaded)
			{
				return;
			}
			foreach (string friendsId in _friendsIds)
			{
				if (!chat.ContainsKey(friendsId))
				{
					chat.Add(friendsId, new Conversation());
				}
				chat[friendsId].unreadMessages += (uint)Load.LoadInt(keyCountUnreadMessages + "_" + friendsId);
			}
			unreadMessagesLoaded = true;
		}

		private void ParseSettingsJson(string result)
		{
			Dictionary<string, object> dictionary = Json.Deserialize(result) as Dictionary<string, object>;
			if (dictionary != null)
			{
				if (dictionary.ContainsKey("RequestFriends"))
				{
					_friendsRequestTime = (long)dictionary["RequestFriends"];
				}
				if (dictionary.ContainsKey("RequestFriendsInChat"))
				{
					_friendsRequestTimeInChat = (long)dictionary["RequestFriendsInChat"];
				}
				if (dictionary.ContainsKey("UpdatePlayerDb"))
				{
					_updatePlayerDBTime = (long)dictionary["UpdatePlayerDb"];
				}
			}
		}

		private IEnumerator RequestTimer()
		{
			yield return new WaitForSeconds(_updatePlayerDBTime);
			canRequestInfo = true;
		}

		private IEnumerator UpdateFriends()
		{
			while (true)
			{
				if (!BCWServer.TryParseIdPlayer(BCWServer.idPlayer))
				{
					yield return null;
					continue;
				}
				yield return StartCoroutine(RequestFriendAndInviteLists());
				yield return new WaitForSeconds(_friendsRequestTime);
			}
		}

		private IEnumerator RequestFriendAndInviteLists()
		{
			while (!BCWServer.TryParseIdPlayer(BCWServer.idPlayer))
			{
				yield return null;
			}
			WWWForm form = new WWWForm();
			form.AddField("action", "update_friends_info");
			form.AddField("id", BCWServer.idPlayer);
			if (messagesToSend.Count > 0)
			{
				form.AddField("private_messages", SerializeMessages());
			}
			form.AddField("app_version", BCWServer._version);
			WWW www = new WWW(headers: new Dictionary<string, string> { 
			{
				"Authorization",
				BCWServer.HashForPush(form.data)
			} }, url: URLs.bcwServer, postData: form.data);
			if (www == null)
			{
				Log("update_friends_info Error www download");
				yield break;
			}
			yield return www;
			string result = BCWServer.Sanitize(www);
			if (!string.IsNullOrEmpty(www.error))
			{
				Log("update_friends_info Error download:  " + www.error);
				yield break;
			}
			if (!string.IsNullOrEmpty(result) && result.Equals("fail"))
			{
				Log("update_friends_info failed ");
				yield break;
			}
			if (string.IsNullOrEmpty(result))
			{
				Log("update_friends_info result is empty");
				yield break;
			}
			Log("update_friends_info result " + result);
			Dictionary<string, object> responseDictionary = Json.Deserialize(result) as Dictionary<string, object>;
			UpdateFriendsIds(responseDictionary);
			UpdateInvitesIds(responseDictionary);
			UpdateBattleInvitesIds(responseDictionary);
			LoadUnreadMessages();
			if (responseDictionary.ContainsKey("chat"))
			{
				Dictionary<string, object> chatDict = responseDictionary["chat"] as Dictionary<string, object>;
				UpdateNewMessages(chatDict);
				UpdateMyMessages(chatDict);
			}
			if (FriendsController.OnIdsListsUpdated != null)
			{
				FriendsController.OnIdsListsUpdated();
			}
		}

		private void UpdateFriendsIds(Dictionary<string, object> responseDictionary)
		{
			if (!responseDictionary.ContainsKey("friends"))
			{
				return;
			}
			uint num = 0u;
			_friendsIds = ParseIdsJson(responseDictionary["friends"] as List<object>);
			foreach (string friendsId in _friendsIds)
			{
				if (!_lastFriendsIds.Contains(friendsId))
				{
					num++;
					_newFriendsIds.Add(friendsId);
				}
			}
			_countNewFriends += num;
			if (num != 0 && FriendsController.OnReciveNewFriends != null)
			{
				FriendsController.OnReciveNewFriends();
			}
			_lastFriendsIds = _friendsIds;
		}

		private void UpdateBattleInvitesIds(Dictionary<string, object> responseDictionary)
		{
			if (!responseDictionary.ContainsKey("fight_invites"))
			{
				return;
			}
			List<object> list = responseDictionary["fight_invites"] as List<object>;
			foreach (object item in list)
			{
				string text = ((long)item).ToString();
				PlayerInfo value = default(PlayerInfo);
				if (playerDB.ContainsKey(text))
				{
					value = playerDB[text];
					value.inviteToBattle = true;
					playerDB[text] = value;
				}
				else
				{
					value.inviteToBattle = true;
					playerDB.Add(text, value);
				}
				if (FriendsController.OnNewBattleInvite != null)
				{
					FriendsController.OnNewBattleInvite(text);
				}
			}
		}

		private void UpdateInvitesIds(Dictionary<string, object> responseDictionary)
		{
			if (!responseDictionary.ContainsKey("invites"))
			{
				return;
			}
			uint num = 0u;
			_invitesIds = ParseIdsJson(responseDictionary["invites"] as List<object>);
			foreach (string invitesId in _invitesIds)
			{
				if (!_lastInviteIds.Contains(invitesId))
				{
					num++;
				}
			}
			if (num != 0 && FriendsController.OnReciveNewInvites != null)
			{
				FriendsController.OnReciveNewInvites();
			}
			_lastInviteIds = _invitesIds;
		}

		private void UpdateNewMessages(Dictionary<string, object> chatDict)
		{
			if (!chatDict.ContainsKey("user_messages"))
			{
				return;
			}
			Dictionary<string, uint> dictionary = new Dictionary<string, uint>();
			foreach (object item in chatDict["user_messages"] as List<object>)
			{
				List<object> list = item as List<object>;
				Message message = new Message();
				message.text = list[0] as string;
				message.timeStamp = (long)list[1];
				message.playerId = list[2] as string;
				if (!chat.ContainsKey(message.playerId))
				{
					chat.Add(message.playerId, new Conversation());
				}
				chat[message.playerId].messages.Add(message);
				chat[message.playerId].sorted = false;
				chat[message.playerId].unreadMessages++;
				if (dictionary.ContainsKey(message.playerId))
				{
					dictionary[message.playerId] = chat[message.playerId].unreadMessages;
				}
				else
				{
					dictionary.Add(message.playerId, chat[message.playerId].unreadMessages);
				}
				if (!newMessages.ContainsKey(message.playerId))
				{
					newMessages.Add(message.playerId, new List<Message>());
				}
				newMessages[message.playerId].Add(message);
				if (timeStamps.ContainsKey(message.playerId))
				{
					timeStamps[message.playerId] = message.timeStamp;
				}
				else
				{
					timeStamps.Add(message.playerId, message.timeStamp);
				}
			}
			if (dictionary.Count > 0 && FriendsController.OnReciveNewMessages != null)
			{
				FriendsController.OnReciveNewMessages(dictionary);
			}
			if (FriendsController.OnUpdateTimestamps != null)
			{
				FriendsController.OnUpdateTimestamps();
			}
		}

		private void UpdateMyMessages(Dictionary<string, object> chatDict)
		{
			if (!chatDict.ContainsKey("user_messages_added"))
			{
				return;
			}
			foreach (KeyValuePair<string, object> item in chatDict["user_messages_added"] as Dictionary<string, object>)
			{
				long key = long.Parse(item.Key);
				if (messagesToSend.ContainsKey(key))
				{
					messagesToSend[key].timeStamp = (long)item.Value;
					if (!chat.ContainsKey(messagesToSend[key].playerId))
					{
						chat.Add(messagesToSend[key].playerId, new Conversation());
					}
					chat[messagesToSend[key].playerId].messages.Add(messagesToSend[key]);
					chat[messagesToSend[key].playerId].sorted = false;
					if (!newMessages.ContainsKey(messagesToSend[key].playerId))
					{
						newMessages.Add(messagesToSend[key].playerId, new List<Message>());
					}
					newMessages[messagesToSend[key].playerId].Add(messagesToSend[key]);
					if (timeStamps.ContainsKey(messagesToSend[key].playerId))
					{
						timeStamps[messagesToSend[key].playerId] = (long)item.Value;
					}
					else
					{
						timeStamps.Add(messagesToSend[key].playerId, (long)item.Value);
					}
					messagesToSend.Remove(key);
				}
			}
			if (SceneManager.GetActiveScene().name.Equals("Lobby"))
			{
				foreach (KeyValuePair<string, Conversation> item2 in chat)
				{
					if (!item2.Value.sorted)
					{
						item2.Value.Sort();
					}
				}
			}
			if (FriendsController.OnUpdateTimestamps != null)
			{
				FriendsController.OnUpdateTimestamps();
			}
		}

		public string SerializeMessages()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			foreach (KeyValuePair<long, Message> item in messagesToSend)
			{
				stringBuilder.Append('{');
				stringBuilder.Append("\"to\": ");
				stringBuilder.Append(item.Value.playerId);
				stringBuilder.Append(',');
				stringBuilder.Append("\"timeStamp\": ");
				stringBuilder.Append(item.Key.ToString());
				stringBuilder.Append(',');
				stringBuilder.Append("\"text\": \"");
				stringBuilder.Append(item.Value.text);
				stringBuilder.Append("\"},");
			}
			stringBuilder.Remove(stringBuilder.Length - 1, 1);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}

		private List<string> ParseIdsJson(List<object> list)
		{
			List<string> list2 = new List<string>();
			foreach (object item in list)
			{
				long result = 0L;
				if (long.TryParse((item as Dictionary<string, object>)["id"].ToString(), out result))
				{
					string text = result.ToString();
					if (BCWServer.TryParseIdPlayer(text))
					{
						list2.Add(text);
					}
					if (playerDB.ContainsKey(text))
					{
						PlayerInfo value = playerDB[text];
						value.gameMode = Convert.ToInt32((item as Dictionary<string, object>)["status"]);
						value.isOnline = value.gameMode > 0;
						playerDB[text] = value;
					}
				}
			}
			return list2;
		}

		private IEnumerator RequestsPlayerInfoCoroutine(List<string> playersIds, Action OnComplete = null, bool force = false, bool saveInStorage = true)
		{
			if (canRequestInfo || force)
			{
				if (!force)
				{
					canRequestInfo = false;
				}
				if (BCWServer.TryParseIdPlayer(BCWServer.idPlayer))
				{
					string requestStr = string.Join(",", playersIds.ToArray());
					Log(requestStr);
					WWWForm form = new WWWForm();
					form.AddField("action", "get_players_info");
					form.AddField("id", BCWServer.idPlayer);
					form.AddField("ids", requestStr);
					form.AddField("app_version", BCWServer._version);
					WWW www = new WWW(headers: new Dictionary<string, string> { 
					{
						"Authorization",
						BCWServer.HashForPush(form.data)
					} }, url: URLs.bcwServer, postData: form.data);
					if (www == null)
					{
						Log("get_players_info Error www download");
						yield break;
					}
					yield return www;
					string result = BCWServer.Sanitize(www);
					if (!string.IsNullOrEmpty(www.error))
					{
						Log("get_players_info Error download:  " + www.error);
					}
					else if (!string.IsNullOrEmpty(result) && result.Equals("fail"))
					{
						Log("get_players_info failed ");
					}
					else if (string.IsNullOrEmpty(result))
					{
						Log("get_players_info result is empty");
					}
					else
					{
						Log("get_players_info result " + result);
						Dictionary<string, object> responseDictionary = Json.Deserialize(result) as Dictionary<string, object>;
						if (responseDictionary.ContainsKey("players"))
						{
							List<object> responseData = responseDictionary["players"] as List<object>;
							if (responseData != null)
							{
								foreach (object element in responseData)
								{
									Dictionary<string, object> tmpDict = element as Dictionary<string, object>;
									if (tmpDict != null)
									{
										PlayerInfo pInfo = new PlayerInfo
										{
											playerId = ((long)tmpDict["id"]).ToString(),
											name = (tmpDict["nick"] as string),
											skinId = (tmpDict["skin"] as string),
											roomName = (tmpDict["room"] as string),
											photonVersion = (tmpDict["photonVersion"] as string)
										};
										int s = 0;
										int.TryParse(tmpDict["status"] as string, out s);
										pInfo.gameMode = s;
										pInfo.isOnline = pInfo.gameMode > 0;
										if (_newFriendsIds.Contains(pInfo.playerId))
										{
											pInfo.isNew = true;
										}
										if (playerDB.ContainsKey(pInfo.playerId))
										{
											pInfo.inviteToBattle = playerDB[pInfo.playerId].inviteToBattle;
											playerDB[pInfo.playerId] = pInfo;
										}
										else
										{
											playerDB.Add(pInfo.playerId, pInfo);
										}
									}
								}
								if (FriendsController.OnUpdatePlayerDB != null)
								{
									FriendsController.OnUpdatePlayerDB();
								}
							}
						}
					}
				}
				if (!force)
				{
					StartCoroutine(RequestTimer());
				}
				if (OnComplete != null)
				{
					OnComplete();
				}
				if (saveInStorage)
				{
					FriendsPlayerStorage.GetInstance().Save();
				}
			}
			yield return null;
		}

		private IEnumerator FriendManagementTemplate(string idPlayer, string action, Action<ServerResponse> OnComplete)
		{
			ServerResponse resultStatus = ServerResponse.WrongFormat;
			if (BCWServer.TryParseIdPlayer(BCWServer.idPlayer) && BCWServer.TryParseIdPlayer(idPlayer))
			{
				resultStatus = ServerResponse.ServerFail;
				WWWForm form = new WWWForm();
				form.AddField("action", action);
				form.AddField("id", BCWServer.idPlayer);
				form.AddField("playerId", idPlayer);
				form.AddField("app_version", BCWServer._version);
				WWW www = new WWW(headers: new Dictionary<string, string> { 
				{
					"Authorization",
					BCWServer.HashForPush(form.data)
				} }, url: URLs.bcwServer, postData: form.data);
				if (www == null)
				{
					Log(action + " Error www download");
					yield break;
				}
				yield return www;
				string result = BCWServer.Sanitize(www);
				if (!string.IsNullOrEmpty(www.error))
				{
					Log(action + " Error download:  " + www.error);
				}
				else if (!string.IsNullOrEmpty(result) && result.Equals("fail"))
				{
					Log(action + " failed ");
				}
				else if (string.IsNullOrEmpty(result))
				{
					Log(action + " result is empty");
				}
				else
				{
					Log(action + " result " + result);
					int resultInt = -1;
					if (int.TryParse(result, out resultInt))
					{
						resultStatus = (ServerResponse)resultInt;
						if (resultStatus == ServerResponse.Successful)
						{
							switch (action)
							{
							case "accept_friendship_invite":
								_invitesIds.Remove(idPlayer);
								_friendsIds.Add(idPlayer);
								break;
							case "reject_friendship_invite":
								_invitesIds.Remove(idPlayer);
								break;
							case "reject_friend":
								_friendsIds.Remove(idPlayer);
								break;
							}
						}
					}
				}
			}
			if (OnComplete != null)
			{
				OnComplete(resultStatus);
			}
			yield return null;
		}

		private IEnumerator FindPlayerIEnumerator(string request, Action<List<PlayerInfo>> OnComplete = null)
		{
			List<PlayerInfo> response = new List<PlayerInfo>();
			if (BCWServer.TryParseIdPlayer(BCWServer.idPlayer))
			{
				WWWForm form = new WWWForm();
				form.AddField("action", "get_players_by_name");
				form.AddField("id", BCWServer.idPlayer);
				form.AddField("name", request);
				form.AddField("app_version", BCWServer._version);
				WWW www = new WWW(headers: new Dictionary<string, string> { 
				{
					"Authorization",
					BCWServer.HashForPush(form.data)
				} }, url: URLs.bcwServer, postData: form.data);
				if (www == null)
				{
					Log("FindPlayerIEnumerator Error www download");
					yield break;
				}
				yield return www;
				string result = BCWServer.Sanitize(www);
				if (!string.IsNullOrEmpty(www.error))
				{
					Log("FindPlayerIEnumerator Error download:  " + www.error);
				}
				else if (!string.IsNullOrEmpty(result) && result.Equals("fail"))
				{
					Log("FindPlayerIEnumerator failed ");
				}
				else if (string.IsNullOrEmpty(result))
				{
					Log("FindPlayerIEnumerator result is empty");
				}
				else
				{
					Log("FindPlayerIEnumerator result " + result);
					Dictionary<string, object> responseDictionary = Json.Deserialize(result) as Dictionary<string, object>;
					if (responseDictionary.ContainsKey("players"))
					{
						List<object> responseData = responseDictionary["players"] as List<object>;
						if (responseData != null)
						{
							foreach (object element in responseData)
							{
								Dictionary<string, object> tmpDict = element as Dictionary<string, object>;
								if (tmpDict != null)
								{
									PlayerInfo pInfo = default(PlayerInfo);
									pInfo.playerId = ((long)tmpDict["id"]).ToString();
									pInfo.name = tmpDict["name"] as string;
									pInfo.skinId = tmpDict["skin"] as string;
									pInfo.gameMode = Convert.ToInt32(tmpDict["status"]);
									pInfo.isOnline = pInfo.gameMode > 0;
									response.Add(pInfo);
								}
							}
						}
					}
				}
			}
			if (OnComplete != null)
			{
				OnComplete(response);
			}
			yield return null;
		}

		private IEnumerator InviteFriendToBattleIENumerator(List<string> playersIds, Action<ServerResponse> OnComplete = null)
		{
			ServerResponse resultStatus = ServerResponse.WrongFormat;
			if (BCWServer.TryParseIdPlayer(BCWServer.idPlayer))
			{
				string requestStr = string.Join(",", playersIds.ToArray());
				Log(requestStr);
				WWWForm form = new WWWForm();
				form.AddField("action", "send_fight_invite");
				form.AddField("id", BCWServer.idPlayer);
				form.AddField("ids", requestStr);
				form.AddField("app_version", BCWServer._version);
				WWW www = new WWW(headers: new Dictionary<string, string> { 
				{
					"Authorization",
					BCWServer.HashForPush(form.data)
				} }, url: URLs.bcwServer, postData: form.data);
				if (www == null)
				{
					Log("get_players_info Error www download");
					yield break;
				}
				yield return www;
				string result = BCWServer.Sanitize(www);
				if (!string.IsNullOrEmpty(www.error))
				{
					Log("get_players_info Error download:  " + www.error);
				}
				else if (!string.IsNullOrEmpty(result) && result.Equals("fail"))
				{
					Log("get_players_info failed ");
				}
				else if (string.IsNullOrEmpty(result))
				{
					Log("get_players_info result is empty");
				}
				else
				{
					Log("get_players_info result " + result);
					int resultInt = -1;
					if (int.TryParse(result, out resultInt))
					{
						resultStatus = (ServerResponse)resultInt;
					}
				}
			}
			if (OnComplete != null)
			{
				OnComplete(resultStatus);
			}
			yield return null;
		}

		private void SaveTimestamps()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			foreach (KeyValuePair<string, long> timeStamp in timeStamps)
			{
				stringBuilder.Append("[\"" + timeStamp.Key + "\"," + timeStamp.Value + "],");
			}
			if (FriendsIds.Count != 0)
			{
				stringBuilder.Remove(stringBuilder.Length - 1, 1);
			}
			stringBuilder.Append("]");
			Save.SaveString(keyTimestamps, stringBuilder.ToString());
		}

		private void LoadTimestamps()
		{
			if (!PlayerPrefs.HasKey(keyTimestamps))
			{
				return;
			}
			List<object> list = Json.Deserialize(Load.LoadString(keyTimestamps)) as List<object>;
			if (list == null)
			{
				return;
			}
			foreach (object item in list)
			{
				if (!timeStamps.ContainsKey((item as List<object>)[0] as string))
				{
					timeStamps.Add((item as List<object>)[0] as string, (long)(item as List<object>)[1]);
				}
			}
		}

		private void SaveFriendsAndInvites()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			stringBuilder.Append(_countNewFriends + ",[");
			foreach (string friendsId in FriendsIds)
			{
				stringBuilder.Append(friendsId + ",");
			}
			if (FriendsIds.Count != 0)
			{
				stringBuilder.Remove(stringBuilder.Length - 1, 1);
			}
			stringBuilder.Append("],[");
			foreach (string newFriendsId in _newFriendsIds)
			{
				stringBuilder.Append(newFriendsId + ",");
			}
			if (_newFriendsIds.Count != 0)
			{
				stringBuilder.Remove(stringBuilder.Length - 1, 1);
			}
			stringBuilder.Append("]]");
			Save.SaveString(keyArrays, stringBuilder.ToString());
		}

		private void LoadFriendsAndInvites()
		{
			if (!PlayerPrefs.HasKey(keyArrays))
			{
				return;
			}
			List<object> list = Json.Deserialize(Load.LoadString(keyArrays)) as List<object>;
			_countNewFriends = Convert.ToUInt32(list[0]);
			foreach (object item in list[1] as List<object>)
			{
				_lastFriendsIds.Add(((long)item).ToString());
			}
			foreach (object item2 in list[2] as List<object>)
			{
				_newFriendsIds.Add(((long)item2).ToString());
			}
		}

		private void SaveChatHistory()
		{
			foreach (KeyValuePair<string, Conversation> item in chat)
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("[" + item.Value.unreadMessages + ",");
				stringBuilder.Append("[");
				foreach (Message message in item.Value.messages)
				{
					stringBuilder.Append("[");
					stringBuilder.Append("\"" + message.text + "\",");
					stringBuilder.Append(message.timeStamp + ",");
					stringBuilder.Append((!message.isMine) ? "0" : "1");
					stringBuilder.Append("]");
				}
				stringBuilder.Append("]]");
				Save.SaveString(_chatHistoryPrefix + item.Key, stringBuilder.ToString());
			}
			PlayerPrefs.Save();
		}

		private void LoadChatHistory(string idPlayer)
		{
			List<Message> list = new List<Message>();
			if (PlayerPrefs.HasKey(_chatHistoryPrefix + idPlayer))
			{
				List<object> list2 = Json.Deserialize(Load.LoadString(_chatHistoryPrefix + idPlayer)) as List<object>;
				if (list2.Count > 1)
				{
					foreach (object item in list2[1] as List<object>)
					{
						Message message = new Message();
						message.text = (item as List<object>)[0] as string;
						message.timeStamp = (long)(item as List<object>)[1];
						message.isMine = (long)(item as List<object>)[2] > 0;
						list.Add(message);
					}
				}
			}
			chat[idPlayer].messages.AddRange(list.ToArray());
		}

		private void Log(string str)
		{
			BCWDebug.Log(str, "Friends");
		}
	}
}
